package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dxy.api.dto.request.*;
import org.dxy.api.response.R;
import org.dxy.domain.adapter.port.CommandHandler;
import org.dxy.domain.command.workorder.*;
import org.dxy.infrastructure.persistent.service.WorkOrderViewService;
import org.dxy.infrastructure.entity.query.WorkOrderViewEntity;
import org.dxy.trigger.http.service.WorkOrderApplicationService;
import org.dxy.types.common.CommandResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 工单应用服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WorkOrderApplicationServiceImpl implements WorkOrderApplicationService {
    
    private final CommandHandler<CreateWorkOrderCommand, Long> createHandler;
    private final CommandHandler<ReleaseWorkOrderCommand, Void> releaseHandler;
    private final CommandHandler<StartWorkOrderCommand, Void> startHandler;
    private final CommandHandler<SuspendWorkOrderCommand, Void> suspendHandler;
    private final CommandHandler<ResumeWorkOrderCommand, Void> resumeHandler;
    private final CommandHandler<CompleteWorkOrderCommand, Void> completeHandler;
    private final CommandHandler<CloseWorkOrderCommand, Void> closeHandler;
    private final CommandHandler<CancelWorkOrderCommand, Void> cancelHandler;
    private final CommandHandler<UpdateWorkOrderCommand, Void> updateHandler;
    private final CommandHandler<DeleteWorkOrderCommand, Void> deleteHandler;
    private final WorkOrderViewService workOrderViewService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R<Long> create(CreateWorkOrderRequest request) {
        try {
            CreateWorkOrderCommand command = new CreateWorkOrderCommand(
                    request.getWorkOrderCode(),
                    request.getProductModel(),
                    request.getPlannedQuantity(),
                    request.getRouteCode(),
                    request.getProductionLineCode()
            );
            
            CommandResult<Long> result = createHandler.handle(command);
            
            if (result.success()) {
                Long workOrderId = result.data();
                // 保存读模型
                WorkOrderViewEntity viewEntity = WorkOrderViewEntity.builder()
                        .id(workOrderId)
                        .workOrderCode(request.getWorkOrderCode())
                        .productModel(request.getProductModel())
                        .plannedQuantity(request.getPlannedQuantity())
                        .routeCode(request.getRouteCode())
                        .productionLineCode(request.getProductionLineCode())
                        .completedQuantity(0)
                        .build();
                
                workOrderViewService.save(viewEntity);
                
                return R.ok(result.data(), result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("创建工单失败", e);
            return R.fail("创建工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> release(Long workOrderId) {
        try {
            ReleaseWorkOrderCommand command = new ReleaseWorkOrderCommand(workOrderId);
            
            CommandResult<Void> result = releaseHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("下达工单失败, workOrderId={}", workOrderId, e);
            return R.fail("下达工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> start(Long workOrderId) {
        try {
            StartWorkOrderCommand command = new StartWorkOrderCommand(workOrderId);
            
            CommandResult<Void> result = startHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("开始工单失败, workOrderId={}", workOrderId, e);
            return R.fail("开始工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> suspend(Long workOrderId, SuspendWorkOrderRequest request) {
        try {
            SuspendWorkOrderCommand command = new SuspendWorkOrderCommand(workOrderId);
            
            CommandResult<Void> result = suspendHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("暂停工单失败, workOrderId={}", workOrderId, e);
            return R.fail("暂停工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> resume(Long workOrderId) {
        try {
            ResumeWorkOrderCommand command = new ResumeWorkOrderCommand(workOrderId);
            
            CommandResult<Void> result = resumeHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("恢复工单失败, workOrderId={}", workOrderId, e);
            return R.fail("恢复工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> complete(Long workOrderId, CompleteWorkOrderRequest request) {
        try {
            CompleteWorkOrderCommand command = new CompleteWorkOrderCommand(
                    workOrderId,
                    request.getCompletedQuantity()
            );
            
            CommandResult<Void> result = completeHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("完成工单失败, workOrderId={}", workOrderId, e);
            return R.fail("完成工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> close(Long workOrderId, CloseWorkOrderRequest request) {
        try {
            CloseWorkOrderCommand command = new CloseWorkOrderCommand(workOrderId);
            
            CommandResult<Void> result = closeHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("关闭工单失败, workOrderId={}", workOrderId, e);
            return R.fail("关闭工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Void> cancel(Long workOrderId, CancelWorkOrderRequest request) {
        try {
            CancelWorkOrderCommand command = new CancelWorkOrderCommand(workOrderId);

            CommandResult<Void> result = cancelHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("取消工单失败, workOrderId={}", workOrderId, e);
            return R.fail("取消工单失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Page<WorkOrderViewEntity>> list(Page<WorkOrderViewEntity> page, WorkOrderViewEntity query) {
        try {
            LambdaQueryWrapper<WorkOrderViewEntity> wrapper = new LambdaQueryWrapper<>();

            // 动态拼接查询条件
            if (StringUtils.isNotBlank(query.getWorkOrderCode())) {
                wrapper.like(WorkOrderViewEntity::getWorkOrderCode, query.getWorkOrderCode());
            }
            if (StringUtils.isNotBlank(query.getProductModel())) {
                wrapper.eq(WorkOrderViewEntity::getProductModel, query.getProductModel());
            }
            if (StringUtils.isNotBlank(query.getRouteCode())) {
                wrapper.eq(WorkOrderViewEntity::getRouteCode, query.getRouteCode());
            }
            if (StringUtils.isNotBlank(query.getProductionLineCode())) {
                wrapper.eq(WorkOrderViewEntity::getProductionLineCode, query.getProductionLineCode());
            }
            // 其他字段按需追加，例如状态、时间等

            Page<WorkOrderViewEntity> resultPage = workOrderViewService.page(page, wrapper);
            return R.ok(resultPage, "查询成功");
        } catch (Exception e) {
            log.error("查询工单列表失败", e);
            return R.fail("查询工单列表失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<WorkOrderViewEntity> getById(Long workOrderId) {
        try {
            WorkOrderViewEntity workOrder = workOrderViewService.getById(workOrderId);
            if (workOrder != null) {
                return R.ok(workOrder, "查询成功");
            } else {
                return R.fail("工单不存在");
            }
        } catch (Exception e) {
            log.error("查询工单详情失败, workOrderId={}", workOrderId, e);
            return R.fail("查询工单详情失败: " + e.getMessage());
        }
    }
    
    @Override
    public R<Page<WorkOrderViewEntity>> getByStatus(Page<WorkOrderViewEntity> page, String status) {
        try {
            // TODO: 实现按状态分页查询逻辑
            // 这里需要根据实际的查询服务实现
            return R.ok(new Page<>(), "查询成功");
        } catch (Exception e) {
            log.error("按状态查询工单失败, status={}", status, e);
            return R.fail("按状态查询工单失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> update(Long workOrderId, CreateWorkOrderRequest request) {
        try {
            UpdateWorkOrderCommand command = new UpdateWorkOrderCommand(
                    workOrderId,
                    request.getWorkOrderCode(),
                    request.getProductModel(),
                    request.getPlannedQuantity(),
                    request.getRouteCode(),
                    request.getProductionLineCode()
            );
            
            CommandResult<Void> result = updateHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("更新工单失败, workOrderId={}", workOrderId, e);
            return R.fail("更新工单失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> delete(Long workOrderId) {
        try {
            DeleteWorkOrderCommand command = new DeleteWorkOrderCommand(workOrderId);
            
            CommandResult<Void> result = deleteHandler.handle(command);
            
            if (result.success()) {
                return R.ok(result.msg());
            } else {
                return R.fail(result.msg());
            }
        } catch (Exception e) {
            log.error("删除工单失败, workOrderId={}", workOrderId, e);
            return R.fail("删除工单失败: " + e.getMessage());
        }
    }

    @Override
    public R<Void> batchDelete(List<Long> ids) {
        try {
            for (Long id : ids) {
                DeleteWorkOrderCommand command = new DeleteWorkOrderCommand(id);
                CommandResult<Void> result = deleteHandler.handle(command);
            }
            return R.ok();
        } catch (Exception e) {
            log.error("批量删除工单失败, ids={}", ids, e);
            return R.fail("批量删除工单失败: " + e.getMessage());
        }
    }
}